class Solution
{
public:
    bool validSquare(vector<int> &p1, vector<int> &p2, vector<int> &p3, vector<int> &p4)
    {
        // 如果validCorner严格判断45，45，90，则用两个角点就能确定。否则需要更多个
        if (!validCorner(p1, p2, p3, p4))
        {
            return false;
        }
        if (!validCorner(p2, p1, p3, p4))
        {
            return false;
        }
        if (!validCorner(p3, p2, p1, p4))
        {
            return false;
        }
        if (!validCorner(p4, p2, p3, p1))
        {
            return false;
        }
        return true;
    }


    // 判断某个顶点到其他三个点的连线所组成的三个角是否为45，45，90
    // 但由于计算时使用的是平方，所以45，90，135 和 90，135，135的情况也会通过
    bool validCorner(vector<int> &p1, vector<int> &p2, vector<int> &p3, vector<int> &p4)
    {
        vector<double> v1{static_cast<double>(p2[0] - p1[0]), static_cast<double>(p2[1] - p1[1])};
        vector<double> v2{static_cast<double>(p3[0] - p1[0]), static_cast<double>(p3[1] - p1[1])};
        vector<double> v3{static_cast<double>(p4[0] - p1[0]), static_cast<double>(p4[1] - p1[1])};
        vector<double> cosineSquares{cosineSquare(v2, v3), cosineSquare(v1, v3), cosineSquare(v1, v2)};
        sort(cosineSquares.begin(), cosineSquares.end());
        if (cosineSquares[0] != 0.0 || cosineSquares[1] != 0.5 || cosineSquares[2] != 0.5)
        {
            return false;
        }
        return true;
    }

    inline double innerProduct(const vector<double> &v1, const vector<double> &v2)
    {
        return v1[0] * v2[0] + v1[1] * v2[1];
    }

    inline double normSquare(const vector<double> &v)
    {
        return v[0] * v[0] + v[1] * v[1];
    }

    inline double cosineSquare(const vector<double> &v1, const vector<double> &v2)
    {
        return innerProduct(v1, v2) * innerProduct(v1, v2) / normSquare(v1) / normSquare(v2);
    }
};